/* ----------------------------------------------------------------------------
* File: tcp_send.cpp
*
* Desc: Stuffs for sending by TCP transport
*
* Created: 11/03/2011, by Alexey Korshunov
* ---------------------------------------------------------------------------- */
#include "common.h"
#include "utils.h"


/************************************************************************/
/*	Desc: Send data using TCP transport												
	Params:
		data - pointer to data
		size - data size
		timeout - time for waiting of sending accessibility
		log_print - pointer to a output function
	Return:
		size of sent data if successful,
		UTILS_ERROR if error											*/
/************************************************************************/
int UtilsTCPSend(int sock, const void *data, size_t size, int timeout, int *status, FILE *logFile)
{
	fd_set wfds;
	struct timeval tv;
	int ret = 0;

	*status = UTILS_OK;

	// check socket descriptor
	if (sock <= 0)
	{
		*status = UTILS_ERROR;
		if (logFile != NULL)
		{
			fprintf(logFile, "UtilsTCPSend: socket is incorrect, sock = %d\n", sock);
			fflush(logFile);
		}
		return -1;
	}

	FD_ZERO(&wfds);
	FD_SET(sock, &wfds);

	// Select sockets
	if (timeout != WAIT_FOREVER)
	{
		tv.tv_sec = timeout / 1000;							// seconds
		tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;	// microseconds
		ret = select(sock + 1, NULL, &wfds, NULL, &tv);
	}
	else
		// wait forever
		ret = select(sock + 1, NULL, &wfds, NULL, NULL);

	if (ret < 0)	// error
	{
		*status = UTILS_ERROR;
		if (logFile != NULL)
		{
			fprintf(logFile, "UtilsTCPSend: failed to select, %s\n", strerror(errno));
			fflush(logFile);
		}
		return -1;
	}

	if (ret == 0)	// timeout
	{
		*status = UTILS_TIMEOUT;
		if (logFile != NULL)
		{
			fprintf(logFile, "UtilsTCPSend: timeout\n");
			fflush(logFile);
		}
		return -1;
	}

	// Send data
	ret = send(sock, data, size, 0);
	if (ret == -1)
	{
		if (errno != EWOULDBLOCK)	// socket is non-blocking mode
		{
			*status = UTILS_ERROR;
			if (logFile != NULL)
			{
				fprintf(logFile, "UtilsTCPSend: Send is failed, sock = %d, %s\n", sock, strerror(errno));
				fflush(logFile);
			}
			return -1;
		}
	}

	return ret;
}